package com.jctrip.hotel.route.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.jctrip.hotel.common.enums.RouteTypeEnum;
import com.jctrip.hotel.common.enums.SourceEnum;
import com.jctrip.hotel.common.route2source.model.param.Route2SourceCheckPriceAndCountParam;
import com.jctrip.hotel.common.route2source.model.result.Route2SourceCheckPriceAndCountResult;
import com.jctrip.hotel.common.route2source.service.Route2SourceOrderService;
import com.jctrip.hotel.common.util.DateUtil;
import com.jctrip.hotel.common.util.RandomUtil;
import com.jctrip.hotel.domain.dao.HtPricePolicyRangeDao;
import com.jctrip.hotel.domain.entity.*;
import com.jctrip.hotel.route.common.ThreadLocalSession;
import com.jctrip.hotel.route.model.param.CheckPriceAndCountParam;
import com.jctrip.hotel.route.model.result.CheckPriceAndCountResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Author：Haruhi
 * @description:
 * @Date：2023/10/10 14:02
 * @Package：com.jctrip.hotel.route.service
 * @Project：hotel-main
 */
@Slf4j
@Service
public class CheckPriceAndCountService extends RouteService{

    @Autowired
    private Route2SourceOrderService route2SourceOrderService;

    @Autowired
    private HtPricePolicyRangeDao htPricePolicyRangeDao;

    public CheckPriceAndCountResult execute(CheckPriceAndCountParam param) {
        // 价格政策配置
        List<HtPricePolicy> htPricePolicies = getPricePolicies();
        List<String> sourceCodes = htPricePolicies.stream()
                .map(HtPricePolicy::getSourceCode)
                .collect(Collectors.toList());
        // 酒店标准信息
        HtHotelStdInfo htHotelStdInfo = getHotelStdInfo(param.getHotelId(), sourceCodes);
        if (htHotelStdInfo == null) {
            throw new RuntimeException("无效的hotelId");
        }
        // 房型标准信息
        HtRoomTypeStdInfo htRoomTypeStdInfo = getRoomTypeStdInfo(param.getHotelId(), param.getRoomTypeCode());
        if (htRoomTypeStdInfo == null) {
            throw new RuntimeException("无效的roomTypeCode");
        }
        HtPricePolicy htPricePolicy = htPricePolicies.stream()
                .filter(e -> e.getSourceCode().equals(htHotelStdInfo.getSourceCode()))
                .filter(e -> e.getPricePolicyCode().equals(param.getPricePolicyCode()))
                .findAny()
                .orElse(null);
        if (htPricePolicy == null) {
            throw new RuntimeException("无效的pricePolicyId");
        }
        // 价格政策区间配置
        List<HtPricePolicyRange> htPricePolicyRanges = getPricePolicyRanges(htPricePolicy.getPricePolicyId());
        // routeId 和 对应的价格政策配置id肯定是唯一值 作为redis的Key
        String key = htPricePolicy.getRouteId() + "_" + htPricePolicy.getPricePolicyId();
        String sourceId = RandomUtil.getRandomItem(key, htPricePolicy.getSourceIds(), ",");
        HtSourceInfo htSourceInfo = getSourceInfo(sourceId);


        Route2SourceCheckPriceAndCountParam checkPriceAndCountParam = Route2SourceCheckPriceAndCountParam.builder()
                .sourceCode(htHotelStdInfo.getSourceCode())
                .sourceId(htSourceInfo.getSourceId())
                .sourceAppId(htSourceInfo.getSourceAppId())
                .sourceSecret(htSourceInfo.getSourceSecret())
                .extra(htSourceInfo.getExtra())
                .productCode(htPricePolicy.getProductCode())
                .hotelId(param.getHotelId())
                .roomTypeCode(param.getRoomTypeCode())
                .occupancy(param.getOccupancy())
                .roomCount(param.getRoomCount())
                .beginDate(param.getBeginDate())
                .days(param.getDays())
                .breakfastCount(htPricePolicy.getBreakfastCount()) // 默认取价格政策里面配置的早餐数
                .totalPrice(param.getTotalPrice())
                .tolerancePrice(htPricePolicy.getTolerancePrice())
                .raiseFunc(price -> getRaisedPrice(price, htPricePolicyRanges)) // 函数式编程精髓
                .hotelExtra(htHotelStdInfo.getExtra())
                .pricePolicyExtra(htPricePolicy.getExtra())
                .build();

        Route2SourceCheckPriceAndCountResult checkPriceAndCountResult =
                route2SourceOrderService.checkPriceAndCount(checkPriceAndCountParam);

        CheckPriceAndCountResult result = new CheckPriceAndCountResult();
        result.setDescribe(checkPriceAndCountResult.getFail() ? "房态校验失败" : "房态校验成功");
        result.setFail(checkPriceAndCountResult.getFail());
        result.setErrormsg(checkPriceAndCountResult.getErrormsg());
        result.setPriceCalendarBeanList(checkPriceAndCountResult.getPriceCalendarBeanList());
        return result;
    }

    private List<HtPricePolicyRange> getPricePolicyRanges(String pricePolicyId) {
        LambdaQueryWrapper<HtPricePolicyRange> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(HtPricePolicyRange::getPricePolicyId, pricePolicyId);
        return htPricePolicyRangeDao.selectList(queryWrapper);
    }

    /**
     * 获取溢价之后的房价
     */
    private BigDecimal getRaisedPrice(BigDecimal purchasePrice, List<HtPricePolicyRange> htPricePolicyRanges) {
        HtPricePolicyRange htPricePolicyRange = htPricePolicyRanges.stream()
                .filter(e -> purchasePrice.compareTo(e.getRangePriceMin()) >= 0)
                .filter(e -> purchasePrice.compareTo(e.getRangePriceMax()) < 0)
                .findAny()
                .orElse(null);
        if (htPricePolicyRange != null) {
            return purchasePrice
                    .multiply(htPricePolicyRange.getMarkupRate().add(BigDecimal.valueOf(1)))
                    .add(htPricePolicyRange.getMarkupFixed());
        }
        // 注意这里的提示文案，不能返回溢价等内部词语
        throw new RuntimeException("下单金额验证失败，原因未知");
    }
}
